home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / REFERENC / TPR / SOURCE.EXE / DEMOLIST.PAS < prev    next >
Pascal/Delphi Source File  |  1992-08-07  |  6KB  |  243 lines

  1. { DEMOLIST.PAS }
  2. program DemoList;
  3. {
  4. Demonstrates the use of pointers to create a list structure, demonstrates how
  5. list traversal is done in both forwards and backwards directions, and provides
  6. routines to add (or insert) and delete items in the list.
  7.  
  8. You can modify these routines for use as a general purpose list manipulation
  9. tool, by changing the ListEntry data structure to hold other types of data.
  10.  
  11. This demonstration program uses the Dos library routines FindFirst and
  12. FindNext to read the default file subdirectory.
  13. }
  14. uses  Dos;
  15.  
  16. type
  17.   { Data record to create the list structure }
  18.   PListEntry = ^TListEntry;
  19.   TListEntry = record
  20.     DirInfo : SearchRec;
  21.     Next    : PListEntry;
  22.     Previous: PListEntry;
  23.   end; {TListEntry}
  24.  
  25. var
  26.   ListHead : PListEntry;
  27.   ListTail : PListEntry;
  28.  
  29.  
  30. function LowerCase (S : String ) : String;
  31. Var
  32.   I : Integer;
  33. begin
  34.   for I := 1 to length(s)  do
  35.     if ((S[I]>='A') and (S[I]<='Z'))  then
  36.       S[I] :=  Chr( Ord( S[I] ) + 32 );
  37.   LowerCase := S;
  38. end;
  39.  
  40.  
  41.  
  42. procedure InitDirectoryList;
  43. { Initialize the directory list structure.
  44.   For convenience, the first entry contains the default volumne name C:\.
  45. }
  46. begin
  47.   ListHead := New(PListEntry);
  48.   ListHead^.Next := NIL;
  49.   ListHead^.Previous := NIL;
  50.   ListTail := ListHead;
  51.   ListHead^.DirInfo.Name := 'C:\';
  52. end; {InitDirectoryList}
  53.  
  54.  
  55.  
  56. function  AddEntry (     Location : PListEntry;
  57.                      Var ListEntry : SearchRec ) : PListEntry;
  58. Var
  59.   NewEntry  : PListEntry;
  60.   SavedNext : PListEntry;
  61.  
  62. begin
  63.   NewEntry := New ( PListEntry );
  64.   NewEntry^.DirInfo := ListEntry;
  65.  
  66.   If  Location = ListTail  Then
  67.   {Adding an item on to the tail of the list}
  68.   begin
  69.     NewEntry^.Next := NIL;
  70.     NewEntry^.Previous := ListTail;
  71.     ListTail^.Next := NewEntry;
  72.     ListTail := NewEntry;
  73.   end
  74.   else
  75.   {inserting an item within the list}
  76.   begin
  77.     SavedNext := Location^.Next;
  78.     Location^.Next := NewEntry;
  79.  
  80.     NewEntry^.Next := SavedNext;
  81.     NewEntry^.Previous := Location;
  82.  
  83.     SavedNext^.Previous := NewEntry;
  84.     
  85.   end;{begin}
  86.  
  87.   AddEntry := NewEntry;
  88.  
  89. end;{AddEntry}
  90.  
  91.  
  92.  
  93. function  RemoveEntry ( Location : PListEntry;
  94.                         HowMany  : Integer ) : PListEntry;
  95.  
  96. { Starting at the point in the list indicated by 'Location', delete
  97.   'HomeMany' entries from the list.
  98.   Return:  A pointer to the first item after those that were deleted.
  99. }
  100.  
  101. var
  102.   CountOfItems : Integer;
  103.  
  104.   function DeleteEntry ( Location : PListEntry ) : PListEntry;
  105.   begin
  106.     if  Location <> NIL  then
  107.     begin
  108.       If  Location^.Previous <> NIL  Then
  109.         Location^.Previous^.Next := Location^.Next;
  110.       If  Location^.Next <> NIL  Then
  111.         Location^.Next^.Previous := Location^.Previous;
  112.       DeleteEntry := Location^.Next;
  113.       If  Location = ListTail  Then
  114.         ListTail := Location^.Previous;
  115.       Dispose(Location);
  116.     end
  117.     else
  118.       DeleteEntry := NIL;
  119.   end;
  120.  
  121. begin {RemoveEntry}
  122.   For  CountOfItems := 1 to HowMany Do
  123.     Location := DeleteEntry ( Location );
  124.   RemoveEntry := Location;
  125. end;{RemoveEntry}
  126.  
  127.  
  128. function Move_Fwd ( Location : PListEntry;
  129.                     HowFar : Integer ) : PListEntry;
  130. {Starting from 'location' move ahead 'HowFar' items in the list
  131.  and return the new location
  132. }
  133. Var
  134.   I : Integer;
  135. begin
  136.   For  I := 1 to HowFar  Do
  137.     If  Location^.Next <> NIL  Then
  138.       Location := Location^.Next;
  139.   Move_Fwd := Location;
  140. end;{Move_Fwd}
  141.  
  142.  
  143. function Move_Bwd ( Location : PListEntry;
  144.                     HowFar : Integer ) : PListEntry;
  145. {Starting from 'location' move backwards 'HowFar' items in the list
  146.  and return that new location
  147. }
  148. var
  149.   I : Integer;
  150. begin
  151.   for  I := 1 to  HowFar  do
  152.     if  Location^.Previous <> NIL  Then
  153.       Location := Location^.Previous;
  154.   Move_Bwd := Location;
  155. end;{Move_Bwd}
  156.  
  157.  
  158. Procedure DisplayFwdList;
  159. Var
  160.   TempPtr : PListEntry;
  161.  
  162. begin
  163.   TempPtr := ListHead;
  164.   While  TempPtr <> NIL  do
  165.   begin
  166.     writeln(TempPtr^.dirinfo.name);
  167.     tempptr := TempPtr^.Next;
  168.   end;
  169. end;
  170.  
  171. procedure DisplayBwdList;
  172. Var
  173.   TempPtr : PListEntry;
  174.  
  175. begin
  176.   TempPtr := ListTail;
  177.   while  TempPtr <> NIL  do
  178.   begin
  179.     writeln (TempPtr^.dirinfo.name);
  180.     tempptr := TempPtr^.Previous;
  181.   end;
  182. end;
  183.  
  184.  
  185.  
  186. procedure ReadDirectory
  187.   ( StartingEntry : PListEntry );
  188.  
  189. { Purpose:
  190.   Reads the directory contents and inserts
  191.   the list into the directory list beginning at 'StartingEntry'.
  192.  
  193. }
  194. var
  195.   ListEntry : SearchRec;  { Holds the contents of a directory entry
  196.                            consisting of filename, size, etc }
  197.   CurLocation : PListEntry;
  198.   IsADirectory : Boolean;
  199.  
  200. begin
  201.   {Call FindFirst to locate all files.  The '*.*' matches all filenames,
  202.    In this case we want to see ALL files so we use the AnyFile mask.
  203.    Note that for the purpose of this example program we are not doing
  204.    error checking.  We should check the DosError variable after each
  205.    call to FindFirst and FindNext.  Also, its possible that AddEntry
  206.    will run of memory and return a NIL value but we aren't checking
  207.    for that in this simplified application example.
  208.   }
  209.  
  210.   FindFirst( '*.*', AnyFile, ListEntry );
  211.   while  DosError = 0  do
  212.   begin
  213.     if  ListEntry.Name[1] <> '.'  then
  214.       {Add all names other than those beginning with '.'.  This
  215.        eliminates our displaying the '.' and '..' names used by DOS}
  216.     begin
  217.       IsADirectory := (ListEntry.Attr and Directory) = Directory;
  218.       if  not  IsADirectory  then
  219.         ListEntry.Name := LowerCase (ListEntry.Name);
  220.         {We convert file names to lowercase and leave directory names
  221.          in upper case for ease of reading the directory listing}
  222.       StartingEntry := AddEntry ( StartingEntry, ListEntry );
  223.     end; { begin }
  224.     FindNext( ListEntry );
  225.   end; { begin }
  226. end; { ReadDirectory }
  227.  
  228. begin
  229.  
  230.   InitDirectoryList;
  231.  
  232.   ReadDirectory ( ListHead );
  233.  
  234.  
  235.   DisplayFwdList;
  236.   Readln;
  237.  
  238.   DisplayBwdList;
  239.   Readln;
  240.  
  241. end.
  242.  
  243.